package com.gree.scmservice.service.saas.impl;

import com.gree.common.entity.ReturnVo;
import com.gree.common.entity.TablePageData;
import com.gree.framework.entity.SaasTenant;
import com.gree.framework.entity.SaasTenantAddon;
import com.gree.framework.entity.SysClient;
import com.gree.framework.utils.SecurityUtils;
import com.gree.scmservice.config.MultiRouteDataSource;
import com.gree.scmservice.dao.saasDao.SaasTenantDao;
import com.gree.scmservice.entity.saas.vo.SaasTenantPasswordVo;
import com.gree.scmservice.entity.saas.vo.SaasTenantVo;
import com.gree.scmservice.service.saas.SaasTenantService;
import com.threadnew.tnmq.producer.RocketMQProducer;
import org.nutz.dao.Chain;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.Record;
import org.nutz.dao.impl.FileSqlManager;
import org.nutz.dao.impl.NutDao;
import org.nutz.dao.sql.Sql;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;

/**
 * Created by 180686 on 2021/7/8 17:00
 */
@Service
public class SaasTenantServiceImpl implements SaasTenantService {

    @Autowired
    Dao dao;

    @Autowired
    private MultiRouteDataSource dataSource;

    @Autowired
    private SaasTenantDao saasTenantDao;

    @Autowired
    @Qualifier("SaasProducer")
    RocketMQProducer rocketMQProducer;

    /**
     * 成为租户
     * @return
     */
    @Override
    public ReturnVo toBeTenant(String tenantid, Long maxSiteNum, String addon) {
        SaasTenant saasTenant = saasTenantDao.selectSaasSysTenantById(tenantid);
        if(saasTenant.getIsTenant() != null) {
            if(saasTenant.getIsTenant() == 2) {
                return new ReturnVo("500","fail");
            }
        }
        /*生成随机ClientId = oracle数据库用户 (dba对greescmdb2创建的saas开头的20位用户名处理)*/
        long randomtime=System.currentTimeMillis();
        String randomtimestr = Long.toString(randomtime);
        int rannum = (int) (Math.random()*900 + 100);
        String rannumstr = Integer.toString(rannum);
        String clientid = "saas"+randomtimestr+rannumstr;

        /*Auth2客户端基本信息*/
        String client_secret = "123456";
        String authorized_grant_types = "gscmmode,refresh_token";
        String redirect_uri = "";
        Double accesstokenvalidityseconds = 1800D;
        Double refreshtokenvalidityseconds = 1800D;
        String scopes = "server";

        /*检查Oracle是否有存在user*/
        Sql sql2 = Sqls.create("select * from all_users where username=@user");
        sql2.setParam("user",clientid);
        sql2.setCallback(Sqls.callback.entities());
        sql2.setEntity(dao.getEntity(Record.class));
        List<Record> alltabledatas = dao.execute(sql2).getList(Record.class);
        if(alltabledatas.size()>0){
            return new ReturnVo("500","fail");
        }
        /*创建数据库User*/
        Dao dao2 = new NutDao(dataSource,new FileSqlManager("sql/createuser.sqls"));
        String[] keys = dao2.sqls().keys();
        for(String key : keys) {
            Sql sql = dao2.sqls().create(key);
            sql.setVar("user",clientid);
            dao2.execute(sql);
        }
        Dao dao3 = new NutDao(dataSource,new FileSqlManager("sql/smcom.sqls"));
        String[] keys3 = dao3.sqls().keys();
        for(String key : keys3) {
            Sql sql = dao3.sqls().create(key);
            sql.setVar("user",clientid);
            dao3.execute(sql);
        }

        String finalSecret = new BCryptPasswordEncoder().encode(client_secret);

        /*插入权限认证模块*/
        SysClient sysClient = new SysClient();
        sysClient.setClientId(clientid);
        sysClient.setClientSecret("{bcrypt}"+finalSecret);
        sysClient.setAuthorizedGrantTypes(authorized_grant_types);
        sysClient.setAccessTokenValiditySeconds(accesstokenvalidityseconds);
        sysClient.setRedirectUri(redirect_uri);
        sysClient.setRefreshTokenValiditySeconds(refreshtokenvalidityseconds);
        sysClient.setScopes(scopes);
        dao.insert(sysClient);

        /*插入租户信息表*/
        saasTenant.setUpdate_time(LocalDateTime.now());
        saasTenant.setClientId(clientid);
        saasTenant.setIsTenant(1L);
        saasTenant.setMaxSiteNum(maxSiteNum);
        saasTenant.setSiteNum(0L);
        dao.update(saasTenant);

        HashMap<String,Object> map = new HashMap<String, Object>();
        map.put("clientid",clientid);
        map.put("password","123456");

        /*装载数据源*/
        rocketMQProducer.publish(map);

        return new ReturnVo("200","success");
    }

    /**
     * 注册用户
     * @param saasTenantVo
     * @return
     */
    @Override
    public ReturnVo register(SaasTenantVo saasTenantVo) {
        if(!saasTenantVo.getPassword().equals(saasTenantVo.getPassword1())) {
            return new ReturnVo("500","fail","密码不一致");
        }
        long randomtime=System.currentTimeMillis();
        String randomtimestr = Long.toString(randomtime);
        int rannum = (int) (Math.random()*90 + 10);
        String rannumstr = Integer.toString(rannum);
        String sysuid = randomtimestr+rannumstr;

        saasTenantVo.setSysUid(sysuid);
        saasTenantVo.setCreate_time(LocalDateTime.now());
        saasTenantVo.setIsTenant(1L);
        saasTenantVo.setTenant_id(sysuid);
        saasTenantVo.setStatus(1L);

        String finalSecret = new BCryptPasswordEncoder().encode(saasTenantVo.getPassword());
        saasTenantVo.setPassword(finalSecret);
        SaasTenant saasTenant = (SaasTenant)saasTenantVo;
        SaasTenant result = dao.insert(saasTenant);
        return new ReturnVo("200","success",result);
    }

    @Override
    public int addSaasTenant(SaasTenant saasTenant) {
        SaasTenant insert = saasTenantDao.insertSaasSysTenant(saasTenant);
        return insert != null?1:0;
    }

    @Override
    public int updateSaasTenant(SaasTenant saasTenant) {
        SaasTenant updateSaasTenant = saasTenantDao.selectSaasSysTenantById(saasTenant.getTenant_id());
        updateSaasTenant.setSysUid(saasTenant.getSysUid());
        updateSaasTenant.setMobile(saasTenant.getMobile());
        updateSaasTenant.setEmail(saasTenant.getEmail());
        int update = saasTenantDao.updateSaasSysTenant(saasTenant);
        return update;
    }

    @Override
    public int resetPasswordById(SaasTenantPasswordVo saasTenantPasswordVo) {
        String tenantId = saasTenantPasswordVo.getTenantId();
        String password2 = saasTenantPasswordVo.getPassword2();

        SaasTenant saasTenant1 = saasTenantDao.selectSaasSysTenantById(tenantId);
        String finalSecret1 = new BCryptPasswordEncoder().encode(password2);
        saasTenant1.setPassword(finalSecret1);
        return saasTenantDao.updateSaasSysTenant(saasTenant1);
    }

    @Override
    public int resetPasswordOnUser(SaasTenantPasswordVo saasTenantPasswordVo) {
        String password1 = saasTenantPasswordVo.getPassword1();
        String password2 = saasTenantPasswordVo.getPassword2();
        String tenantId = SecurityUtils.getUserWithPasswordMode().get("username").toString();

        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        SaasTenant saasTenant = saasTenantDao.selectSaasSysTenantById(tenantId);
        if (encoder.matches(password1, saasTenant.getPassword())) {
            SaasTenant saasTenant1 = saasTenantDao.selectSaasSysTenantById(tenantId);
            String finalSecret1 = new BCryptPasswordEncoder().encode(password2);
            saasTenant1.setPassword(finalSecret1);
            return saasTenantDao.updateSaasSysTenant(saasTenant1);
        }
        return 0;
    }

    @Override
    public SaasTenant fetchSaasTenant(String tenant_id) {
        SaasTenant saasTenant = saasTenantDao.selectSaasSysTenantById(tenant_id);
        return saasTenant;
    }

    @Override
    public TablePageData<SaasTenant> querySaasTenant(SaasTenant saasTenant) {
        TablePageData<SaasTenant> saasTenantTablePageData = saasTenantDao.selectSaasSysTenantList(saasTenant);
        return saasTenantTablePageData;
    }

    @Override
    public int delSaasTenant(Long[] tenant_ids) {
        int delete = saasTenantDao.deleteSaasSysTenantByIds(tenant_ids);
        return delete;
    }

}
